#include "ChatRoom.h"
#ifdef DEBUG
#include "PrintInfo.h"
#include <iostream>
using std::cout;
#endif

json ChatRoom:: serialize()const{
    json j;
    j["owner_id"]=owner_id;
    j["chat_id"]=chat_id;
    j["chat_name"]=chat_name;
    json user_list_json=json::array();
    for(auto it=user_list.cbegin();it!=user_list.cend();++it){
        json list_item;
        list_item["user_id"]=it->first;
        list_item["user_name"]=it->second;
        
        user_list_json.push_back(list_item);
    }

    json chat_history_json=json::array();
    for(const auto&msg:chat_history){
        chat_history_json.push_back(msg->serializeMsg());
    }
    j["user_list"]=user_list_json;
    j["chat_history"]=chat_history_json;

    #ifdef DEBUG
    cout<<"serialize chat_room:"<<j.dump(4)<<endl;
    #endif 

    return j;
}

void ChatRoom:: unserialize(const json&j){
    owner_id=j["owner_id"];
    chat_id=j["chat_id"];
    chat_name=j["chat_name"];
    user_list.clear();
    for(const auto&list_item:j["user_list"]){
        user_list[list_item["user_id"].get<int>()]=list_item["user_name"];
    }
    chat_history.clear();
    for(const auto&msg_json:j["chat_history"]){
        chat_history.emplace_back(shared_ptr<Msg>(new Msg(msg_json)));
    }
}

int ChatRoom::get_owner_id() const{
    return owner_id;
}

string ChatRoom::get_chat_id() const{
    return chat_id;
}

string ChatRoom::get_name() const{
    return chat_name;
}

map<int,string> ChatRoom::get_user_list() const{
    return user_list;
}

deque<shared_ptr<Msg>> ChatRoom::get_chat_history() const{
    return chat_history;
}

bool ChatRoom::add_user(const int&user_id,const string&user_name){
    this->user_list[user_id]=user_name;
}

bool ChatRoom::remove_user(const int&user_id){
    this->user_list.erase(user_id);
}

bool ChatRoom::is_owner(const int&user_id) const{
    return owner_id==user_id;
}

bool ChatRoom::is_user_in_room(const int&user_id) const{
    return user_list.count(user_id)>0;
}

void ChatRoom::add_chat_msg(shared_ptr<Msg>msg){
    chat_history.push_back(msg);
    if(chat_history.size()>MSG_MAX_SIZE){
        chat_history.pop_front();
    }
}

deque<shared_ptr<Msg>> ChatRoom::get_latest_chat_msg(const int&num_msg) const{
    int num=std::min(num_msg,static_cast<int>(chat_history.size()));
    deque<shared_ptr<Msg>> result;
    for(int i=0;i<num;++i){
        result.push_back(chat_history.at(chat_history.size()-1-i));
    }
    return result;
}

int ChatRoom::get_chat_history_size() const{
    return chat_history.size();
}

shared_ptr<Msg> ChatRoom::get_a_msg(int index){
    return chat_history.at(index);
}
